<style scoped>
	.formButton {
		text-align: right;
		width: 100%;
		border-top: 1px solid #eee;
		padding-top: 16px;
	}
	.boardcast /deep/.ivu-form-item-error .ivu-filter-input .ivu-input {
		border: 1px solid #1563C2 !important;
		box-shadow: 0px 0px 8px #1563C2 !important;
	}

	.editor {
		height: 300px;

	}

	.editor /deep/ .ql-container {
		height: calc(100% - 82px);
		overflow: auto;
	}
	.users-wrapper{
		border: 1px solid rgb(204, 204, 204);
		border-radius: 5px;
		padding: 4px 10px;
		max-height: 300px;
		overflow: auto;
		overscroll-behavior: contain;
	}
</style>
<style>
	.ql-snow.ql-toolbar button.ql-file{
		font-size: 16px;
		display: inline-block;
	    font-family: Ionicons;
	    font-style: normal;
	    font-weight: 400;
	    font-variant: normal;
	    text-transform: none;
	    text-rendering: optimizeLegibility;
	    line-height: 1;
	    -webkit-font-smoothing: antialiased;
	    -moz-osx-font-smoothing: grayscale;
	    vertical-align: -.125em;
	    text-align: center;
	}
	.ql-snow.ql-toolbar button.ql-file:before {
	    content: "\F255";
	}
</style>
<template>
	<div class="boardcast" style="padding: 10px">
		<Form ref="formValidateScene" :model="formValidateScene" :rules="formValidateSceneRule" :label-width="100">
			<FormItem label="类型" prop="receiverType">
				<RadioGroup v-model="formValidateScene.receiverType" @on-change="changeReceiverType">
					<Radio :label='1'>接入组</Radio>
					<Radio :label='2'>个人</Radio>
				</RadioGroup>
			</FormItem>
			<FormItem label="接入组" prop="accessGroups">
				<Transfer :data="showAccessGroupList" :list-style="listStyle" :target-keys="formValidateScene.accessGroups" :filter-method="filterMethod" :operations="['移除','选择']" :titles="['未选接入组','已选接入组']" filterable @on-change="getAccessGroupMember"></Transfer>
			</FormItem>
			<FormItem label="成员" prop="accessGroups_copy" style="max-height: 200px;overflow: auto;">
				<div :class="{'users-wrapper':formValidateScene.accessGroups_copy.length > 0 ? true : false}">
					<div v-for="group in formValidateScene.accessGroups_copy" :key="group.id">
						{{group.name}}
						<CheckboxGroup v-model="group.userIds">
							<Checkbox :label="user.userId" v-for="user in group.userList" :key="`${group.id}-${user.userId}`" :disabled="group.disabled">{{user.userName}}</Checkbox>
						</CheckboxGroup>
					</div>
				</div>
			</FormItem>
			<FormItem label="公告类型" prop="type">
				<RadioGroup v-model="formValidateScene.type">
					<Radio :label=1><span class="sw">事务公告</span></Radio>
					<Radio :label=3><span class="wg">违规公告</span></Radio>
				</RadioGroup>
			</FormItem>
			<FormItem label="内容" prop="content">
				<quill-editor v-model="formValidateScene.content" class="editor" ref="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)">
				</quill-editor>
				<div style="text-align:right;">
					{{tiLength}}/500
				</div>
				<span style="color:#f90"> <Icon type="ios-information-circle-outline" />仅允许粘贴文本内容，粘贴内容中的图片、链接和样式将无效</span>
				<Upload ref="upload" style="display:inline-block" :show-upload-list="false" :on-success="handleSuccess" 
					:on-format-error="handleFormatErrorImg" :format="['jpg','jpeg','png','gif']"  multiple :action="uploadUrl">
					<Button icon="ios-cloud-upload-outline" id="imgUploadBtn" v-show="false"></Button>
				</Upload>
				<Upload ref="fileUpload" style="display:inline-block" :show-upload-list="false" :on-success="handleFileSuccess" 
					:on-format-error="handleFormatErrorFile" :format="['pdf']"  multiple :action="fileUploadUrl">
					<Button icon="ios-cloud-upload-outline" id="fileUploadBtn" v-show="false"></Button>
				</Upload>
			</FormItem>
			<FormItem class="formButton">
				<Button @click="cancel('formValidateScene')">取消</Button>
				<Button type="primary" @click="sendToScene()" :loading="disabledSend" style="margin-left: 8px">发送</Button>
			</FormItem>
		</Form>
	</div>
</template>
<script>
import encryption from '@/libs/encryption.js'
	import {
		quillEditor
	} from "vue-quill-editor"; // 调用编辑器
	import 'quill/dist/quill.core.css'
	import 'quill/dist/quill.snow.css'
	import 'quill/dist/quill.bubble.css'
	//引入Qill插件
	import Quill from "quill";
	let Link = Quill.import("formats/link");
	// 自定义a链接
	class FileBlot extends Link {
		// 继承Link Blot
		static create(value) {
			let node = undefined;
			if(value && !value.href) {
				// 适应原本的Link Blot
				node = super.create(value);
			} else {
				// 自定义Link Blot
				node = super.create(value.href);
				node.innerText = value.innerText;
				node.href = value.href;
				node.id = value.id;
				node.setAttribute("title", '点击可下载:'+value.innerText);
				node.setAttribute("data-value", value.dataValue);
			}
			return node;
		}
	}
	FileBlot.blotName = "link";
	FileBlot.tagName = "A";
	//注册FileBlot
	Quill.register(FileBlot);
	import {
		sendToSence,sendToSenceDis
	} from '@/api/boardcast_new.js'
	import {
		getaccessgrouplist
	} from '@/api/access_new.js'
	const toolbarOptions = [
		["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
		[{header: 1}, {header: 2}], // 1、2 级标题
		[{script: "sub"}, {script: "super"}], // 上标/下标
		[{indent: "-1"}, {indent: "+1"}], // 缩进
		[{size: ["small", false, "large", "huge"]}], // 字体大小
		[{header: [1, 2, 3, 4, 5, 6, false]}], // 标题
		[{color: []}, {background: []}], // 字体颜色、字体背景颜色
		[{align: []}], // 对齐方式
		["clean"], // 清除文本格式
		["image"], // 链接、图片、视频
		["file"] // 文件链接
	];
	export default {
		components: {
			quillEditor,
		},
		props:['sceneId','sceneName','isDistributed','isMainRange'],
		data() {
			const validateGroupUserNum = (rule, value, callback) => { //验证只能填入数字		         
				//验证警戒值		    
				if(value.length > 0) {
					value.forEach(group => {
						if(group.userIds.length == 0) {
							callback(new Error('每组请至少选择一个用户'));
						} else {
							callback()
						}
					})
				} else {
					callback()
				}
			}
			return {
				tiLength: 0,
				userID:'',
				accessGroupList: [],
				formValidateScene: {
					"sencensType": "",
					"receiverType": 1,
					"sceneId": this.sceneId || this.$route.query.id,
					"accessGroups": [
					],
					"accessGroups_copy": [],
					"content": "",
					"id": "",
					"title": "",
					"type": 1
				},
				accessGroups_copy: [],
				formValidateSceneRule: {
					sceneId: [{
						required: true,
						message: '请选择场景',
						trigger: 'change'
					}],
					type: [{
						required: true,
						type: 'number',
						message: '请选择场景类型',
						trigger: 'change'
					}],
					receiverType: [{
						required: true,
						type: 'number',
						message: '不能为空',
						trigger: 'change'
					}],
					accessGroups: [{
						required: true,
						type: "array",
						min: 1,
						message: '不能为空',
						trigger: 'change'
					}],
					"accessGroups_copy": [{
						required: true,
						type: "array",
						min: 1,
						message: '不能为空',
						trigger: 'change'
					}, {
						validator: validateGroupUserNum,
						trigger: 'change'
					}],
					content: [{
						required: true,
						message: '请输入内容',
						trigger: 'change'
					}]
				},
				listStyle: {
					width: '200px',
					height: '300px'
				},
				editorOption: {
					modules: {
						clipboard: {
							// 粘贴版，处理粘贴时候带图片
							matchers: [
								[Node.ELEMENT_NODE, this.handleCustomMatcher]
							],
						},
						toolbar: {
							container: toolbarOptions, //工具菜单栏配置
							handlers: {
								'image': (value) => {
									if(value) {
										document.querySelector('#imgUploadBtn').click()
									} else {
										this.quill.format('image', false);
									}
								},
								'file': (value) => {
									if(value) {
										document.querySelector('#fileUploadBtn').click()
									}
								}
							}
						},
					},
					placeholder: '请输入内容', //提示
				},
				uploadUrl: '',
				fileUploadUrl:'',
				setUpLoadHead: {
					'Authorization': localStorage.getItem('token')
				},
				disabledSend: false
			}
		},
		computed: {
			editor() {
				return this.$refs.myQuillEditor.quill;
			},
			showAccessGroupList() {
				return this.accessGroupList.map(group => {
					return {
						key: group.id,
						label: group.name
					}
				})
			}
		},
		created(){
       // 获取用户id
       let November = sessionStorage.getItem('November')
        November = JSON.parse(encryption.SelfUseDecrypt(November))
        this.userID = November.userId
        },
		mounted() {
			this.uploadUrl = `/api/minio/upload/permanent?visibility=company&type=images&bucket=images`;
			this.fileUploadUrl = `/api/minio/upload/permanent?visibility=company&type=docs&bucket=docs`;
			this.getAccessGroupList();
			//发送文件图标添加title
			let fileUplodEle = document.querySelector('.ql-formats .ql-file');
			fileUplodEle.setAttribute("title", '上传pdf文件');
		},
		methods: {
			// 上传图片，上传成功后使用图片地址生成img元素插入富文本光标处
			handleSuccess(res) {
				if(res.code == 1) {
					// 获取光标所在位置
					let quill = this.$refs.myQuillEditor.quill
					let length = quill.getSelection().index;
					// 插入图片，res为服务器返回的图片链接地址
					let url = `/Learn/${res.data}`
					quill.insertEmbed(length, 'image', url);
				} else {
					this.$Message.error(data.message);
				}
			},
			// 上传文件，上传成功后将文件地址生成超链接插入富文本光标处
			handleFileSuccess(res) {
				if(res.code == 1) {
					// 获取光标所在位置
					let quill = this.$refs.myQuillEditor.quill
					let length = quill.getSelection().index || 1;
					// 插入图片，res为服务器返回的图片链接地址
					let url = `${this.baseURL}/minio/download?path=${res.data}`; // `/Learn/${res.data}`
					quill.insertEmbed(length, 'text', "[");
					quill.insertEmbed(length+1, 'link', {
						href: url,
						innerText: res.info.originalName,
						id:res.info.id,
						dataValue:`/Learn/${res.data}`
					}, "api");
					quill.insertEmbed(length+res.info.originalName.length +1, 'text', "]");
				} else {
					this.$Message.error(data.message);
				}
			},
			// 图片格式验证失败时的回调函数
			handleFormatErrorImg(){
				this.$Message.warning('仅允许上传pdf,jpg,png,gif格式文件');
			},
			// 格式验证失败时的回调函数
			handleFormatErrorFile(){
				this.$Message.warning('仅允许上传pdf格式文件');
			},
            // 获取竞赛、演练场景下的接入组列表，过滤掉没有用户的空的接入组
			getAccessGroupList() {
                let testId = this.sceneId || this.$route.query.id
				if(!testId){ // 数据不正确，不需要获取
					return;
				}
				let params = {
					pageIndex: 1,
					pageSize: 2147483647,
					testId
				};
				getaccessgrouplist(params).then(data => {
					if(data.code == 1) {
						this.accessGroupList = data.data.items.filter(group => group.userList.length > 0);
						this.formValidateScene.accessGroups = [];
						this.formValidateScene.accessGroups_copy = [];
					} else if(data.code == -2) {
						this.accessGroupList = [];
					} else {
						this.$Message.warning(data.message);
					}
				})
			},
            // 接入组选中组改变时的回掉函数
			getAccessGroupMember(ids) {
				this.formValidateScene.accessGroups = ids;
				this.formValidateScene.accessGroups_copy = ids.map(id => { // 遍历选中的组，生成指定格式的返回数据
					let group = this.accessGroupList.find(group => group.id == id)
					if(this.formValidateScene.receiverType == 1) { // 发送接入组类型公告，成员全选，并设置复选框禁用
						this.$set(group, 'checkAll', true);
						this.$set(group, 'disabled', true);
						this.$set(group, 'groupId', group.id);
						this.$set(group, 'userIds', group.userList.map(user => user.userId));
						group.checkAll = true;
					} else { // 发送个人类型公告，成员全不选，复选框不禁用
						group.checkAll = false;
						this.$set(group, 'checkAll', false);
						this.$set(group, 'disabled', false);
						this.$set(group, 'groupId', group.id);
						this.$set(group, 'userIds', []);
					}
					return group;
				})
			},
            // 发送公告，发送成功通知父组件隐藏模态框
			sendToScene() {
				this.disabledSend = true;
				this.$refs.formValidateScene.validate((valid) => {
					if(valid) {
						let userIds = [];
						let params = {
							sceneId: this.formValidateScene.sceneId,
							noticeSceneDto: {
								"accessGroups": this.formValidateScene.accessGroups_copy.map((group,index) => {
									let filtersUserIds = [];
									if(index > 0){
										filtersUserIds = group.userIds.filter(userId => !userIds.includes(userId))
									}else{
										filtersUserIds = group.userIds;
									}
									userIds = userIds.concat(group.userIds);
									return {
										groupId: group.groupId,
										userIds: filtersUserIds
									}
								}),
								"content": this.formValidateScene.content,
								"id": this.formValidateScene.id,
								"title": this.formValidateScene.title,
								"type": this.formValidateScene.type
							}
						}
						if(this.sceneName){
							params.noticeSceneDto.sceneName = this.sceneName;
							params.noticeSceneDto.sender = this.userID;
						}
						let apiName=(this.isDistributed==1&&this.isMainRange==1)?sendToSenceDis:sendToSence
						apiName(params).then(data => {
							if(data.code == 1) {
								this.$Message.info('发送成功');
								this.$emit('hideModal');
							} else {
								this.$Message.error(data.message);
							}
							this.disabledSend = false;
						}).catch(error => {
							this.$Message.error('公告发送失败');
							this.disabledSend = false;
						})
					} else {
						this.disabledSend = false;
					}
				})
			},
            // 取消发送时，重置验证同时发送hideModal事件，让父组件隐藏模态框
			cancel(name) {
				this.$refs[name].resetFields();
				this.$emit('hideModal');
			},
            // 以下三个为富文本的相关事件回掉函数，用于后续扩展，暂时保留
			onEditorBlur() {}, // 失去焦点事件
			onEditorFocus() {}, // 获得焦点事件
			onEditorChange(event) {
				if(this.formValidateScene.content===''){
					this.tiLength = 0
				}
				else{
					this.tiLength = event.quill.getLength()-1
				}
				if (this.tiLength > 500) {
					event.quill.deleteText(500, this.tiLength - 500);
				}
			}, // 内容改变事件
            // 穿梭框组件用于过滤的回调函数
			filterMethod(data, query) {
				return data.label.indexOf(query) > -1
			},
            // 切换接入组/个人类型的回掉函数
			changeReceiverType(type) {
				if(type == 2) { // 个人类型，解除禁用，人员全不选
					this.formValidateScene.accessGroups_copy.forEach(group => {
						group.disabled = false;
						group.checkAll = false;
						group.userIds = [];
					})
				} else { // 接入组类型，选择禁用，人员全选
					this.formValidateScene.accessGroups_copy.forEach(group => {
						group.disabled = true;
						group.checkAll = true;
						group.userIds = group.userList.map(user => user.userId);
					})
				}
			},
            // 粘贴时候，除纯文本外的内容全部忽略
			handleCustomMatcher(node, Delta) {
				let ops = []
				Delta.ops.forEach(op => {
					if(op.insert && typeof op.insert === 'string') { // 只有纯文本是字符串类型，其他包括图片、文件等，均忽略掉
						ops.push({ // 只保留粘贴内容，格式全部舍弃
							insert: op.insert,
						})
					}
					if (op.insert && op.insert.image && op.insert.image.indexOf('/Learn') !== -1) {
						ops.push({ // 保留本系统包含的图片
							insert: op.insert,
						})
					}
				})
				Delta.ops = ops
				return Delta
			}
		}
	}
</script>